﻿namespace Arms.Domain.Modules.Geography.Extensions
{
    using Arms.Framework.Geography;
    using System;
    using System.Collections.Generic;
    using System.Data.Entity.Spatial;

    public static class PointBaseRepositoryExtensions
    {
        /// <summary>
        /// Finds a PointBase (country, province etc..) by its pointID.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="repository"></param>
        /// <param name="pointID"></param>
        /// <returns></returns>
        public static T FindByPointID<T>(this IRepository<T> repository, int pointID) where T : PointBase
        {
            return repository.First(x => x.PointID == pointID);
        }
        /// <summary>
        /// Finds a PointBase (country, province etc...) by its lat/long.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="repository"></param>
        /// <param name="latitude"></param>
        /// <param name="longitude"></param>
        /// <returns></returns>
        public static T FindByPointLatLong<T>(this IRepository<T> repository, double latitude, double longitude) where T : PointBase
        {
            return repository.First(x => x.Point.Data.Latitude == latitude && x.Point.Data.Longitude == longitude);
        }
        /// <summary>
        /// Gets a list of PointBases (country, province etc...) within specified distance(metres) of the origin.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="repository"></param>
        /// <param name="origin"></param>
        /// <param name="distance"></param>
        /// <returns></returns>
        public static IEnumerable<T> GetWithinDistance<T>(this IRepository<T> repository, DbGeography origin, double distance) where T : PointBase
        {
            return repository.Get(x => x.Point.Data.Distance(origin) <= distance);
        }
        /// <summary>
        /// Gets a list of PointBases (country, province etc...) within specified distance(metres) of its lat/long.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="repository"></param>
        /// <param name="latitude"></param>
        /// <param name="longitude"></param>
        /// <param name="distance"></param>
        /// <returns></returns>
        public static IEnumerable<T> GetWithinDistance<T>(this IRepository<T> repository, double latitude, double longitude, double distance) where T : PointBase
        {
            return repository.Get(x => x.Point.Data.Distance(GeographyHelper.CreatePoint(latitude, longitude)) <= distance);
        }
    }
}
